/** \file ncis/ncis.h
 * \brief Network Communication to Internal Structure
 * \author Vincent MAUGE <vmauge@gmail.com>
 *
 * ncis.h : library to convert commands packet to internal structure.
 *
 * This library is designed for YOP: http://code.google.com/p/yopp2p/
 */

#ifndef NCIS_H
#define NCIS_H

#include <stdio.h>
#include "../global.h"
#include "../osocklib/osocklib.h"
#include "../sharedmemory/sharedmemory.h"
#include "../chainedlib/chainedlist.h"

/// length max of an error message
#define LENGTH_MAX_ERROR_MESSAGE 256


///define protocol value
#define NCIS_PROTO_UDP 1
#define NCIS_PROTO_TCP 2

/// type of a delay
typedef unsigned int aodelay_t;

/// type of a checksum
typedef filekey_t checksum_t;
 

/** \brief File command structure
 * 
 */
typedef struct _ncis_file_s{
	char filename[FILENAME_MAX];
	filekey_t key;
	off_t size;
	ip_t ip;
	in_port_t port;
} ncis_file_s;

/** \brief Get command structure
 *
 */
typedef struct _ncis_get_s{
	filekey_t key;
	off_t begin;
	off_t end;
} ncis_get_s;

/** \brief Ready command structure
 *
 */
typedef struct _ncis_ready_s{
	filekey_t key;
	aodelay_t delay;
	ip_t ip;
	in_port_t port;
	char proto;
	off_t begin;
	off_t end;
} ncis_ready_s;

/** \brief Checksum command structure
 *
 */
typedef struct _ncis_checksum_s{
	filekey_t key;
	off_t block_size;
	off_t begin;
	checksum_t checksum;
} ncis_checksum_s;

/** \brief Info command structure
 *
 */

typedef struct _ncis_info_s{
	filekey_t key;
} ncis_info_s;


/** \brief Neighbour command structure
 *
 */
typedef ip_port_s ncis_neighbour_s;


/** \brief Redirect command structure
 *
 */

typedef struct _ncis_redirect_s{
	filekey_t key;
	ip_t ip;
	in_port_t port;
} ncis_redirect_s;


/** \brief Error command structure
 *
 */
typedef struct _ncis_error_s{
	char ncis_type;
	char message[LENGTH_MAX_ERROR_MESSAGE];
} ncis_error_s;



/** \brief Standard command structure
 *
 */
typedef struct _ncis_standard_s{
	enum {
	NCIS_CONNECTED,
	NCIS_LIST,
	NCIS_FILE,
	NCIS_GET,
	NCIS_TRAFFIC,
	NCIS_READY,
	NCIS_CHECKSUM,
	NCIS_CHECKSUM_LAST,
	NCIS_INFO,
	NCIS_NEIGHBOURHOOD,
	NCIS_NEIGHBOUR,
	NCIS_REDIRECT,
	NCIS_ERROR
	} type;
	union{
	ncis_file_s file;
	ncis_get_s get;
	ncis_ready_s ready;
	ncis_checksum_s checksum;
	ncis_info_s info;
	ncis_neighbour_s neighbour;
	ncis_redirect_s redirect;
	ncis_error_s error;
	};
} ncis_standard_s;


/** \ brief Get command type 
 * \param command 
 * \return return the type of the command or -1 if error	
 */

int NCIS_get_ncis_type(const char * command, size_t commandlen);

/** \brief Convert Network packet to ncis structure
 * \param ncis_root root of the chained_list of ncis structure where we add the conversion of np (many node could be add for checksum packet).
 * \param np network packet received
 * \TODO code checksum type
 * \return 0 or >1 if ok  or <0 if error
 */
int NCIS_np2ncis(CLNode_s * ncis_root,  npacket_s * np);

/** \brief Convert ncis structure to Network packet
 * \param np network packet create using first packet or more (if necessary for checksum)
 * \param ncis_root pointer to a chained liste of ncis_standard_s
 * \warning to send a checksum you have to be sure that the chained list contains a NCIS_CHECKSUM_LAST
 * \return 0 or -1 if error
 */
int NCIS_ncis2np(npacket_s * np, CLNode_s * ncis_root);

/** \brief Print the content of the ncis packet
 * \param stream as printf function
 * \param ncis pointer to printed structur
 */
int NCIS_fprintf(FILE * stream, const ncis_standard_s * np);

/** \brief Get a 32 char which represents a key or a checksum
 * \param key stock the computed key
 * \param data must start with a key (32 char only in 0123456789abcdef)
 * \return 0 if ok or -1 if error
 */
int NCIS_get_key(filekey_t key,char * data); 


/**
 *
 */
int NCIS_launch(SM_elem_s * sm_ncis, SM_elem_s * sm_father, msd_s * socket);

#endif

/* end of ncis.h */
